﻿using System;


namespace unitlib
{
    public interface IUnit
    {
        double Value { get; }
        string Unit { get; }
        string  LatexUnit { get; }
    }

    public static partial class UnitValueEx
    {
        internal static double Parse(this string str)
        {
            if (string.IsNullOrEmpty(str)) return 0d;

            int index = 0;
            double result = 0d;
            int sign = 1;
            double fraction = 0d;
            int fractionDigits = 0;
            int exponent = 0;
            int exponentSign = 1;

            // 1. 处理符号
            if (str[index] == '-' || str[index] == '+')
            {
                sign = str[index] == '-' ? -1 : 1;
                index++;
            }

            // 2. 处理整数部分
            while (index < str.Length && str[index] >= '0' && str[index] <= '9')
            {
                result = result * 10 + (str[index] - '0');
                index++;
            }

            // 3. 处理小数部分
            if (index < str.Length && str[index] == '.')
            {
                index++;
                double scale = 1d;
                while (index < str.Length && str[index] >= '0' && str[index] <= '9')
                {
                    fraction = fraction * 10 + (str[index] - '0');
                    scale *= 10;
                    index++;
                    fractionDigits++;
                }
                if (fractionDigits > 0)
                {
                    result += fraction / scale;
                }
            }

            // 4. 处理科学计数法（e/E）
            if (index < str.Length && (str[index] == 'e' || str[index] == 'E'))
            {
                index++;
                // 处理指数符号
                if (index < str.Length && (str[index] == '-' || str[index] == '+'))
                {
                    exponentSign = str[index] == '-' ? -1 : 1;
                    index++;
                }
                // 处理指数值
                while (index < str.Length && str[index] >= '0' && str[index] <= '9')
                {
                    exponent = exponent * 10 + (str[index] - '0');
                    index++;
                }
            }
            // 5. 应用科学计数法
            if (exponent != 0)
            {
                exponent *= exponentSign;
                double power = 1d;
                for (int i = 0; i < exponent; i++) power *= 10;
                for (int i = 0; i > exponent; i--) power /= 10;
                result *= power;
            }
            return result * sign;
        }
        public static string ValueUnit(this IUnit unit) => $"{unit.Value} {unit.Unit}";
        public static string ValueLatexUnit(this IUnit unit) => $"{unit.Value}\\;{unit.LatexUnit}";
    }
    /// <summary>
    /// 不带单位，用于系数使用
    /// </summary>
    public readonly struct UnitValue : IUnit
    {
        public double Value { get; }
        public string Unit => string.Empty;
        public string LatexUnit => string.Empty;
        public UnitValue(double value) { Value = value; }
        public UnitValue Round(int digits) => new UnitValue(Math.Round(Value, digits));
        //数值与字符串转换
        public override string ToString() => Value.ToString();
        public static implicit operator UnitValue(double value) => new UnitValue(value);
        public static implicit operator double(UnitValue value) => value.Value;
        public static implicit operator UnitValue(string value) => new UnitValue(value.Parse());

        //常规运算
        public static UnitValue operator +(UnitValue left, UnitValue right) => new UnitValue(left.Value + right.Value);
        public static UnitValue operator -(UnitValue left, UnitValue right) => new UnitValue(left.Value - right.Value);
        public static UnitValue operator *(UnitValue left, UnitValue right) => new UnitValue(left.Value * right.Value);
        public static UnitValue operator /(UnitValue left, UnitValue right) => new UnitValue(left.Value / right.Value);
        public static UnitValue operator ^(UnitValue left, UnitValue right) => new UnitValue(Math.Pow(left.Value, right.Value));
        //比较运算
        public static bool operator ==(UnitValue left, UnitValue right) => left.Equals(right);
        public static bool operator !=(UnitValue left, UnitValue right) => !left.Equals(right);
        public override bool Equals(object obj)
        {
            return obj is UnitValue other && other.Value == Value;
        }
        public override int GetHashCode()
        {
            unchecked
            {
                return GetType().GetHashCode() * 31 + Value.GetHashCode();
            }
        }
    }


    /// <summary>
    /// 模板
    /// </summary>
    //public readonly struct Unit_ : IUnit
    //{
    //    public double Value { get; }
    //    public string Unit => "";
    //    public string LatexUnit => "";

    //    public Unit_(double value) { Value = value; }
    //    public Unit_ Round(int digits) => new Unit_(Math.Round(Value, digits));
    //    //数值与字符串转换
    //    public override string ToString() => Value.ToString();
    //    public static explicit operator Unit_(double value) => new Unit_(value);
    //    public static explicit operator double(Unit_ value) => value.Value;
    //    public static implicit operator Unit_(string value) => new Unit_(value.Parse());
    //    //比较运算
    //    public static bool operator ==(Unit_ left, Unit_ right) => left.Equals(right);
    //    public static bool operator !=(Unit_ left, Unit_ right) => !left.Equals(right);
    //    public static bool operator <(Unit_ left, Unit_ right) => left.Value < right.Value;
    //    public static bool operator >(Unit_ left, Unit_ right) => left.Value > right.Value;
    //    public static bool operator <=(Unit_ left, Unit_ right) => left.Value <= right.Value;
    //    public static bool operator >=(Unit_ left, Unit_ right) => left.Value >= right.Value;
    //    public override bool Equals(object obj) => obj is Unit_ other && other.Value == Value;
    //    public override int GetHashCode()
    //    {
    //        unchecked
    //        {
    //            return GetType().GetHashCode() * 31 + Value.GetHashCode();
    //        }
    //    }
    //    //常规运算
    //    public static Unit_ operator +(Unit_ left, Unit_ right) => new Unit_(left.Value + right.Value);
    //    public static Unit_ operator -(Unit_ left, Unit_ right) => new Unit_(left.Value - right.Value);
    //    public static Unit_ operator *(Unit_ left, UnitValue right) => new Unit_(left.Value * right.Value);
    //    public static Unit_ operator *(UnitValue left, Unit_ right) => new Unit_(left.Value * right.Value);
    //    public static Unit_ operator /(Unit_ left, UnitValue right) => new Unit_(left.Value / right.Value);
    //    public static UnitValue operator /(Unit_ left, Unit_ right) => new UnitValue(left.Value / right.Value);
    //    //新增运算  
    //}
}
